////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Roman Ranzmaier (http://www.ranzmaier.at/contact.aspx).  All rights reserved.
// 
// Codeplex project: http://gadgeteernetworking.codeplex.com
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using System;
using Microsoft.SPOT;
using System.Net;
using System.Net.Sockets;

namespace Ranzmaier.NETMF.GadgeteerNetworking
{

    /// <summary>
    /// Supported ProtocolType for the connection.            
    /// </summary>
    public enum NetworkServerProtocol
    {
        TCP,
        UDP
    }


    /// <summary>
    /// Baseclass for TCP and UDP server
    /// </summary>
    public abstract class NetWorkServerBase : IDisposable
    {

        #region public properties
        /// <summary>
        /// Gets the server protocol.
        /// </summary>
        public NetworkServerProtocol Protocol { get; private set; }
        /// <summary>
        /// Gets the port.
        /// </summary>
        public int Port { get; private set; }
        /// <summary>
        /// Gets the timeout.
        /// </summary>
        public int Timeout { get; private set; }
        /// <summary>
        /// Gets or sets a value indicating whether this <see cref="NetWorkServerBase"/> is started.
        /// </summary>
        /// <value>
        ///   <c>true</c> if started; otherwise, <c>false</c>.
        /// </value>
        public bool Started { get; protected set; }
        #endregion

        protected System.Net.Sockets.Socket _socket;

        /// <summary>
        /// Initializes a new instance of the <see cref="NetWorkServerBase"/> class.
        /// </summary>
        /// <param name="protocol">The protocol.</param>
        /// <param name="adr">The IP adress.</param>
        /// <param name="port">The port.</param>
        /// <param name="timeout">The sockettimeout.</param>
        internal NetWorkServerBase(NetworkServerProtocol protocol, IPAddress adr, int port, int timeout)
        {
            this.Port = port;
            this.Protocol = protocol;
            this.Timeout = timeout;
            Started = false;


        }
        /// <summary>
        /// Creates the socket.
        /// </summary>
        protected void CreateSocket()
        {
            _socket = new System.Net.Sockets.Socket(
                AddressFamily.InterNetwork,
                 Protocol == NetworkServerProtocol.TCP ? SocketType.Stream : SocketType.Dgram,
                Protocol == NetworkServerProtocol.TCP ? ProtocolType.Tcp : ProtocolType.Udp);
            _socket.ReceiveTimeout = Timeout;
            _socket.SendTimeout = Timeout;
        }


        #region abstract Methods
        /// <summary>
        /// Starts this instance.
        /// </summary>
        public abstract void Start();
        /// <summary>
        /// Stops this instance.
        /// </summary>
        public abstract void Stop();
        #endregion

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        public void Dispose()
        {
            Stop();

            if (_socket != null)
                _socket.Close();
        }
    }
}
